/**
 * Copyright (c) 2012 Nokia Corporation.
 */

package com.nokia.example.simplepurchase.uicomponents;

import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.lcdui.Graphics;

import com.nokia.mid.ui.CanvasGraphicsItem;

/**
 * Custom progress bar.
 */
public class ProgressBar extends CanvasGraphicsItem {
	// Constants
	public static final int HEIGHT = 6;
	private static final int BACKGROUND_COLOR = 0xff99aacc;
	private static final int FOREGROUND_COLOR = 0xff5588ff;
	private static final int DEFAULT_TIMEOUT = 10000; // In milliseconds
	private static final int TIMER_INTERVAL = 500; // In milliseconds
	
	// Members
	private Listener _listener = null;
	private Timer _timer = null;
	private int _value = 0;
	private int _width = 0;
	private int _height = 0;
	private int _barIncrement = 100 / (DEFAULT_TIMEOUT / TIMER_INTERVAL);
	
	/**
	 * Constructor.
	 * @param width
	 * @param height
	 */
	public ProgressBar(int width, int height, Listener listener) {
		super(width, height);
		_width = width;
		_height = height;
		_listener = listener;
	}

	/**
	 * From CanvasGraphicsItem.
	 * Paints the progress bar.
	 */
	protected void paint(Graphics graphics) {
		graphics.setColor(BACKGROUND_COLOR);
		graphics.fillRect(1, _height / 2, _width - 2, _height);
		graphics.setColor(FOREGROUND_COLOR);
		graphics.fillRect(0, 0, _width * _value / 100, _height - 1);
	}
	
	/**
	 * Sets the progress value.
	 * @param value The progress value to set in percentages, [0, 100].
	 */
	public void setValue(final int value) {
		if (value < 0) {
			_value = 0;
		}
		else if (value > 100) {
			_value = 100;
		}
		else {
			_value = value;
		}
		
		repaint();
		
		if (_listener != null) {
			_listener.onValueChanged(_value);
		}
	}
	
	/**
	 * Starts the progress bar.
	 */
	public void start(final int timeout) {
		if (timeout <= 0) {
			// Invalid argument
			return;
		}
		
		stop(0);
		_barIncrement = 100 / (timeout / TIMER_INTERVAL);
		_timer = new Timer();
		_timer.scheduleAtFixedRate(new ProgressTimerTask(),
				TIMER_INTERVAL, TIMER_INTERVAL);
	}
	
	/**
	 * Stops the progress bar.
	 */
	public void stop(final int value) {
		try {
			if (_timer != null) {
				_timer.cancel();
				_timer = null;
			}
		}
		catch (IllegalStateException e) {}
		catch (Exception e) {}
		
		setValue(value);
	}
	
	/**
	 * Listener for timeout events. 
	 */
	public interface Listener {
		void onValueChanged(int value);
		void onTimeout();
	}
	
	/**
	 * Timer task for increasing the value of the progress bar. 
	 */
	private class ProgressTimerTask extends TimerTask {
		public void run() {
			if (_value >= 100) {
				stop(100);
				
				if (_listener != null) {
					_listener.onTimeout();
				}
				
				return;
			}
			
			setValue(_value + _barIncrement);
		}
	}
}
